package com.liaoyi.myble.service;

import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;

import java.util.List;
import java.util.UUID;

public class BluetoothService extends Service {
    private String TAG = "BluetoothService";

    private BluetoothBinder mBinder = new BluetoothBinder();
    private BluetoothManager bluetoothManager;
    public BluetoothAdapter bluetoothAdapter;
    public BluetoothGatt bluetoothGatt;
    private IBluetoothScan iBluetoothScan;
    private BluetoothLeScanner bluetoothLeScanner;
    private BluetoothGattCharacteristic mBluetoothGattCharacteristic;
    public BluetoothGattCharacteristic mBluetoothGattCharacteristicNotify;


    // 蓝牙连接状态
    private int mConnectionState = 0;
    // 蓝牙连接已断开
    private final int STATE_DISCONNECTED = 0;
    // 蓝牙正在连接
    private final int STATE_CONNECTING = 1;
    // 蓝牙已连接
    private final int STATE_CONNECTED = 2;

    // 蓝牙已连接
    public final static String ACTION_GATT_CONNECTED = "com.ly.ble.ACTION_GATT_CONNECTED";
    // 蓝牙已断开
    public final static String ACTION_GATT_DISCONNECTED = "com.ly.ble.ACTION_GATT_DISCONNECTED";
    // 发现GATT服务
    public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.ly.ble.ACTION_GATT_SERVICES_DISCOVERED";
    // 收到蓝牙数据
    public final static String ACTION_DATA_AVAILABLE = "com.ly.ble.ACTION_DATA_AVAILABLE";
    // 连接失败
    public final static String ACTION_CONNECTING_FAIL = "com.ly.ble.ACTION_CONNECTING_FAIL";
    // 蓝牙数据
    public final static String EXTRA_DATA = "com.ly.ble.EXTRA_DATA";

    // 服务标识
    private final UUID SERVICE_UUID = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
    // 特征标识（读取数据）
    private final UUID CHARACTERISTIC_READ_UUID = UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb");
    // 特征标识（发送数据）
    private final UUID CHARACTERISTIC_WRITE_UUID = UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb");
    // 描述标识
    private final UUID DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        release();
        return super.onUnbind(intent);
    }

    /**
     * 释放相关资源
     */
    public void release() {
        if (bluetoothGatt == null) {
            return;
        }
        bluetoothGatt.close();
        bluetoothGatt = null;
    }

    /**
     * 初始化蓝牙
     *
     * @return true     获取BluetoothManager成功
     * false    获取BluetoothManager失败
     */
    public Boolean initBluetooth() {
        if (bluetoothManager == null) {
            bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            if (bluetoothManager == null) {
                Log.e(TAG, "initBluetooth: " + "获取BluetoothManage失败");
                return false;
            }
        }
        bluetoothAdapter = bluetoothManager.getAdapter();
        if (bluetoothAdapter == null) {
            Log.e(TAG, "initBluetooth: " + "获取BluetoothManager失败");
            return false;
        }
        return true;
    }

    /**
     * 扫描的回调函数
     */
    ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            iBluetoothScan.onScanResult(result.getDevice());
            super.onScanResult(callbackType, result);
        }
    };
    /**
     * 连接的回调函数
     */
    BluetoothGattCallback gattCallback = new BluetoothGattCallback() {

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            switch (newState) {
                case STATE_DISCONNECTED:
                    mConnectionState = STATE_DISCONNECTED;
                    Log.e(TAG, "onConnectionStateChange: 断开连接" );
                    sendBleBroadcast(ACTION_GATT_DISCONNECTED);
                    break;
                case STATE_CONNECTING:
                    mConnectionState = STATE_CONNECTING;
                    Log.e(TAG, "onConnectionStateChange: 连接中");
                    break;
                case STATE_CONNECTED :
                    mConnectionState = STATE_CONNECTED;
                    Log.e(TAG, "onConnectionStateChange: 连接成功");
                    sendBleBroadcast(ACTION_GATT_CONNECTED);
                    // 要想获取到uuid必须执行这行指令
                    gatt.discoverServices();
                    break;
            }
        }

        /**
         *  gatt.discoverServices()执行后的回调
         * @param gatt
         * @param status
         */
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            BluetoothGattService gattService = gatt.getService(SERVICE_UUID);
            if(gattService == null){
                sendBleBroadcast(ACTION_CONNECTING_FAIL);
                return;
            }
            mBluetoothGattCharacteristic = gattService.getCharacteristic(CHARACTERISTIC_READ_UUID);
            if(mBluetoothGattCharacteristic == null){
                sendBleBroadcast(ACTION_CONNECTING_FAIL);
                return;
            }
            BluetoothGattDescriptor mBluetoothGattDescriptor = mBluetoothGattCharacteristic.getDescriptor(DESCRIPTOR_UUID);
            mBluetoothGattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            if (bluetoothGatt.writeDescriptor(mBluetoothGattDescriptor)) {
                // 蓝牙设备在数据改变时，通知App，App在收到数据后回调onCharacteristicChanged方法
                bluetoothGatt.setCharacteristicNotification(mBluetoothGattCharacteristic, true);
            }

            mBluetoothGattCharacteristicNotify = gattService.getCharacteristic(CHARACTERISTIC_WRITE_UUID);
            if(mBluetoothGattCharacteristic == null){
                sendBleBroadcast(ACTION_CONNECTING_FAIL);
                return;
            }
            // bluetoothGatt.setCharacteristicNotification(mBluetoothGattCharacteristicNotify, true);
           /* BluetoothGattDescriptor descriptorNotify = mBluetoothGattCharacteristicNotify.getDescriptor(DESCRIPTOR_UUID);
            descriptorNotify.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            if (bluetoothGatt.readDescriptor(descriptorNotify)) {
                Log.e(TAG, "onServicesDiscovered: 可读" );
                // 蓝牙设备在数据改变时，通知App，App在收到数据后回调onCharacteristicChanged方法
                bluetoothGatt.setCharacteristicNotification(mBluetoothGattCharacteristicNotify, true);
            }*/
        }

        /**
         * 接收到数据的回调函数
         * @param gatt
         * @param characteristic
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            sendBleBroadcast(ACTION_DATA_AVAILABLE,characteristic);
        }

        /**
         * 发送数据后的回调
         * @param gatt
         * @param characteristic
         * @param status
         */
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 发送成功
                Log.i(TAG, "onCharacteristicWrite: 发送成功" );
            } else {
                // 发送失败
                Log.i(TAG, "onCharacteristicWrite: 发送失败" );
            }
        }
    };


    /**
     * 发送通知
     *
     * @param action 广播Action
     */
    private void sendBleBroadcast(String action) {
        Intent intent = new Intent(action);
        sendBroadcast(intent);
    }

    /**
     * 发送通知
     *
     * @param action         广播Action
     * @param characteristic 数据
     */
    private void sendBleBroadcast(String action, BluetoothGattCharacteristic characteristic) {
        Intent intent = new Intent(action);
        if (CHARACTERISTIC_READ_UUID.equals(characteristic.getUuid())) {
            intent.putExtra(EXTRA_DATA, characteristic.getValue());
        }
        sendBroadcast(intent);
    }

    /**
     * 开始扫描
     */
    public void startScan() {
        Log.e(TAG, "scan: 开始扫描");
        bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        bluetoothLeScanner.startScan(scanCallback);
    }

    /**
     * 停止扫描
     */
    public void stopScan() {
        Log.e(TAG, "stopScan: 停止扫描");
        iBluetoothScan.stopScan();
        bluetoothLeScanner.stopScan(scanCallback);
    }

    /**
     * 服务相关
     */
    public class BluetoothBinder extends Binder {
        public BluetoothService getService() {
            return BluetoothService.this;
        }
    }

    public void setiBluetoothScan(IBluetoothScan iBluetoothScan) {
        this.iBluetoothScan = iBluetoothScan;
    }

    public void connected(String mac) {
        BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(mac);
        bluetoothGatt = bluetoothDevice.connectGatt(this, false, gattCallback);
    }

    public void disconnected(){
        bluetoothGatt.disconnect();
    }

}
